package net.hserver.gateway.core;

import cn.hserver.core.ioc.IocUtil;
import cn.hserver.core.server.util.HServerIpUtil;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;
import net.hserver.gateway.core.bean.Proxy;
import net.hserver.gateway.core.bean.RouterInfo;
import net.hserver.gateway.core.node.Manager;
import net.hserver.gateway.core.node.ServerNodeManager;
import net.hserver.gateway.core.statistics.SimpleStatistics;
import net.hserver.gateway.core.strategy.LoadBalancingStrategy;
import net.hserver.gateway.core.strategy.ServerNode;
import net.hserver.gateway.core.strategy.Strategy;



/**
 * @author hxm
 */
@Slf4j
public class ProxyHandler {

    static Proxy builder(ChannelHandlerContext ctx,Object msg,Proxy proxy) {
        proxy.setMsg(msg);
        proxy.setCtx(ctx);
        return proxy;
    }

    static Proxy proxyInfo(Proxy proxy) {
        Strategy<ServerNode> strategy = IocUtil.getBean(LoadBalancingStrategy.class);
        HttpRequest msg = (HttpRequest) proxy.getMsg();
        Manager manager = IocUtil.getBean(ServerNodeManager.class);
        RouterInfo routerInfo = manager.getRouterIdByUrl(msg.uri());
        ServerNode serverNode;
        switch (routerInfo.getStrategyType()) {
            case 轮询法:
                serverNode = strategy.polling(routerInfo.getRouterId());
                break;
            case 加权轮询法:
                serverNode = strategy.weightPolling(routerInfo.getRouterId());
                break;
            case 源地址哈希法:
                serverNode = strategy.hashConsistency(routerInfo.getRouterId(), HServerIpUtil.getClientIp(proxy.getCtx()));
                break;
            case 最小连接数法:
                serverNode = strategy.minimumConnection(routerInfo.getRouterId());
                break;
            default:
                serverNode = strategy.random(routerInfo.getRouterId());
                break;
        }
        proxy.setServerNode(serverNode);
        return proxy;
    }

    static Proxy statistics(Proxy proxy) {
        Object httpRequest = proxy.getMsg();
        if (httpRequest instanceof HttpRequest) {
            //开始统计
            SimpleStatistics bean = IocUtil.getBean(SimpleStatistics.class);
            bean.uv(proxy.getCtx());
            bean.pv();
            bean.platform((HttpRequest) httpRequest);
        }
        return proxy;
    }

}
